<template>
  <div id="virtual-list" ref="warp" @scroll="handScroll">
    <div ref="scrollHeight"></div>
    <div class="visibleWarp" :style="{ transform: `translateY(${offset}px)` }">
      <div v-for="item in visibleList" :key="item.id" :id="item.id">
        <slot :item="item"></slot>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  name: "virtual-list",
  props: {
    size: Number,
    remain: Number,
    dataList: Array
  },
  data() {
    return {
      start: 0,
      end: this.remain,
      offset: 0
    };
  },
  computed: {
    visibleList() {
      return this.dataList.slice(this.start, this.end);
    }
  },
  mounted() {
    this.$refs.scrollHeight.style.height =
      this.size * this.dataList.length - 1 + "px";
    this.$refs.warp.style.height = this.remain * this.size + "px";
  },
  methods: {
    handScroll() {
      // 获取滚动条的滚动的距离
      const scrollTop = this.$refs.warp.scrollTop;
      this.start =
        Math.floor(scrollTop / this.size) - 1 >= 0
          ? Math.floor(scrollTop / this.size)
          : 0;
      this.end = this.start + this.remain;
      // 计算列表移动的偏移值
      this.offset = this.start * this.size;
    }
  }
};
</script>

<style lang="scss">
#virtual-list {
  position: relative;
  overflow-y: auto;
}
.visibleWarp {
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  z-index: 2;
}
</style>
